package com.pennphoto.client;

import java.util.ArrayList;

import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.*;
import com.google.gwt.dom.client.Style.Unit;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.logical.shared.SelectionHandler;
import com.google.gwt.event.logical.shared.SelectionEvent;

public class PhotoRegisterView implements EntryPoint{

	
	RootPanel rootPanel;
	int userId;
	DialogBox dialogBox=new DialogBox();
	DialogBox newPhotoBox=new DialogBox();
	DialogBox commentBox=new DialogBox();
	DialogBox photoVsBox = new DialogBox();
	ArrayList<ViewedPhotos> photos = new ArrayList<ViewedPhotos>();
	final Label textToServerLabel = new Label();
	final HTML serverResponseLabel = new HTML();
	Button closeButton = new Button();
	Button commentCloseButton = new Button();
	Button newCloseButton = new Button();
	Button setVisibility = new Button();
	Button updateVisibility = new Button();
	int currentPhotoIndex=0;
	HTMLPanel deckPanel=new HTMLPanel("");
	 TextBox comment = new TextBox();
	 TextBox description = new TextBox();
	 TextBox tag = new TextBox();
	 TextBox url = new TextBox();
	 ListBox rating = new ListBox(false);
	 ListBox vsLevel = new ListBox(false);
	 ListBox circles = new ListBox(true);
	 ListBox friends = new ListBox(true);
	 Button savePhoto = new Button("Save Photo");
	 Button postComment = new Button("Post Comment");
	private static final String SERVER_ERROR = "An error occurred while "
			+ "attempting to contact the server. Please check your network "
			+ "connection and try again.";
	PennPhotoCRUDServiceAsync photoService = GWT.create(PennPhotoCRUDService.class);
	
	public PhotoRegisterView(int userId)
	{
		this.userId=userId;
		
	}
	
	@Override
	public void onModuleLoad() {
		dialogBox= new DialogBox();
		newPhotoBox = new DialogBox();
		commentBox = new DialogBox();
		photoVsBox = new DialogBox();
		// TODO Auto-generated method stub
		rootPanel = RootPanel.get();
		rootPanel.setSize("100%", "800px");
		
		DockLayoutPanel dockLayoutPanel = new DockLayoutPanel(Unit.EM);
		rootPanel.add(dockLayoutPanel, 44, 26);
		dockLayoutPanel.setSize("90%", "100%");
		
		
		
		AbsolutePanel absolutePanel = new AbsolutePanel();
		dockLayoutPanel.addNorth(absolutePanel, 7.7);
		
		HTMLPanel panel = new HTMLPanel("Photo Options");
		dockLayoutPanel.addWest(panel, 7.7);
		panel.setHeight("80%");
		
		
		HTMLPanel panel_1 = new HTMLPanel("Photo details:");
		dockLayoutPanel.addEast(panel_1, 7.7);
		panel_1.setHeight("80%");
		
		Image image = new Image("img/penn.jpg");
		absolutePanel.add(image, 10, 0);
		image.setSize("100px", "100px");
		
		Label lblSearchPhotoBy = new Label("Search Photo by tags:");
		absolutePanel.add(lblSearchPhotoBy, 218, 72);
		
		final TextBox textBox = new TextBox();
		absolutePanel.add(textBox, 354, 60);
		deckPanel = new HTMLPanel("PhotoStream");
		
		dockLayoutPanel.add(deckPanel);
		deckPanel.setSize("517px", "100%");
		
		closeButton = new Button("Close");
		// We can set the id of a widget by accessing its Element
		closeButton.getElement().setId("closeButton");
		VerticalPanel dialogVPanel = new VerticalPanel();
		dialogVPanel.addStyleName("dialogVPanel");
		dialogVPanel.add(new HTML("<b>Sending name to the server:</b>"));
		dialogVPanel.add(textToServerLabel);
		dialogVPanel.add(new HTML("<br><b>Server replies:</b>"));
		dialogVPanel.add(serverResponseLabel);
		dialogVPanel.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT);
		dialogVPanel.add(closeButton);
		dialogBox.setWidget(dialogVPanel);
		closeButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				dialogBox.hide();				
			}
		});
		
		commentCloseButton = new Button("Close");
		// We can set the id of a widget by accessing its Element
		commentCloseButton.getElement().setId("commentCloseButton");
		VerticalPanel dialogVPanel1 = new VerticalPanel();
		dialogVPanel1.addStyleName("dialogVPanel1");
		dialogVPanel1.add(new HTML("<b>Enter your comment here:</b>"));
		dialogVPanel1.add(comment);
		dialogVPanel1.add(new HTML("<b>Choose your rating here:</b>"));		
		rating.addItem(String.valueOf(5));
		rating.addItem(String.valueOf(4));
		rating.addItem(String.valueOf(3));
		rating.addItem(String.valueOf(2));
		rating.addItem(String.valueOf(1));
		dialogVPanel1.add(rating);
		dialogVPanel1.add(postComment);
		/*postComment.addClickHandler(new ClickHandler(){
			public void onClick(ClickEvent event)
			{
				commentBox.hide();
			}
		});*/
		dialogVPanel.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT);
		dialogVPanel1.add(commentCloseButton);
		commentBox.setWidget(dialogVPanel1);
		commentCloseButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				commentBox.hide();				
			}
		});
		newCloseButton = new Button("Close");
		// We can set the id of a widget by accessing its Element
		
		newCloseButton.getElement().setId("newCloseButton");
		VerticalPanel dialogVPanel2 = new VerticalPanel();
		dialogVPanel2.addStyleName("dialogVPanel1");
		dialogVPanel2.add(new HTML("<b>Enter url of new photo:</b>"));
		dialogVPanel2.add(url);
		dialogVPanel2.add(new HTML("<br><b>Enter description:</b>"));
		dialogVPanel2.add(description);
		dialogVPanel2.add(new HTML("<br><b>Enter tag:</b>"));
		dialogVPanel2.add(tag);		
		dialogVPanel2.add(new HTML("<br><b>Set visibility:</b>"));
		dialogVPanel2.add(vsLevel);
		vsLevel.addItem("Everyone");
		vsLevel.addItem("Circles");
		vsLevel.addItem("A few of my friends");
		
		vsLevel.addChangeHandler(new ChangeHandler(){

			@Override
			public void onChange(ChangeEvent event) {
				if(vsLevel.getItemText(vsLevel.getSelectedIndex()).equals("Circles"))
				{
					//fetch user circles and show
					photoService.getCircleNames(userId, new AsyncCallback<ArrayList<String>>(){

						@Override
						public void onFailure(Throwable caught) {
							dialogBox
							.setText("Remote Procedure Call - Failure");
					serverResponseLabel
							.addStyleName("serverResponseLabelError");
					serverResponseLabel.setHTML(SERVER_ERROR+" "+caught.getMessage());
					dialogBox.center();
					caught.printStackTrace();
					closeButton.setFocus(true);
							
						}

						@Override
						public void onSuccess(ArrayList<String> result) {
							circles.setEnabled(true);
							for(String c:result)
								circles.addItem(c);
							
						}
					
					});
				}else if(vsLevel.getItemText(vsLevel.getSelectedIndex()).equals("A few of my friends")){
					photoService.getFriendNames(userId, new AsyncCallback<ArrayList<String>>(){

						@Override
						public void onFailure(Throwable caught) {
							dialogBox
							.setText("Remote Procedure Call - Failure");
					serverResponseLabel
							.addStyleName("serverResponseLabelError");
					serverResponseLabel.setHTML(SERVER_ERROR+" "+caught.getMessage());
					dialogBox.center();
					caught.printStackTrace();
					closeButton.setFocus(true);
							
						}

						@Override
						public void onSuccess(ArrayList<String> result) {
							friends.setEnabled(true);
							for(String f:result)
								friends.addItem(f);
						}
						
					});
					
				}
				
			}
		});
		
		dialogVPanel2.add(new HTML("<br><b>Choose Circles:</b>"));
		circles.setVisibleItemCount(5);
		dialogVPanel2.add(circles);
		circles.setEnabled(false);
		
		dialogVPanel2.add(new HTML("<br><b>Choose Friends:</b>"));
		friends.setVisibleItemCount(5);
		dialogVPanel2.add(friends);
		friends.setEnabled(false);
		
		
		dialogVPanel2.add(savePhoto);
		savePhoto.addClickHandler(new PhotoAddHandler());
		dialogVPanel2.add(newCloseButton);
		newPhotoBox.setWidget(dialogVPanel2);
		newCloseButton.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				newPhotoBox.hide();				
			}
		});
		
		Button btnAddPhoto = new Button("Add photo");
		btnAddPhoto.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				newPhotoBox.center();
			}
		});
		panel.add(btnAddPhoto);
		
		Button btnSearch = new Button("Search");
		btnSearch.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
				if(textBox.getText()!=null && !textBox.getText().equals(""))
				{
					String query= textBox.getText();
					query = PhotoRegisterView.escapeHtml(query);
					getSearchResults(query);
				}
			}
		
		});
		
		absolutePanel.add(btnSearch, 538, 60);
		
		HTML htmlPennPhotoGallery = new HTML("<h3> Penn Photo Gallery</h3>", true);
		absolutePanel.add(htmlPennPhotoGallery, 140, 10);
		
		Button btnHome = new Button("Home");		
		btnHome.addClickHandler(new ClickHandler() {
			public void onClick(ClickEvent event) {
			rootPanel.clear();
			UserProfile u= new UserProfile(userId);
			u.onModuleLoad();
			History.newItem("");
			}
		});
		absolutePanel.add(btnHome, 675, 60);
			
		//start populating the stackpanel with images from the photo stream:
		
		photoService.getPhotoStream(userId, new AsyncCallback<ArrayList<ViewedPhotos>>() {
				public void onFailure(Throwable caught) {
					// Show the RPC error message to the user
					dialogBox
							.setText("Remote Procedure Call - Failure");
					serverResponseLabel
							.addStyleName("serverResponseLabelError");
					serverResponseLabel.setHTML(SERVER_ERROR+" "+caught.getMessage());
					dialogBox.center();
					caught.printStackTrace();
					closeButton.setFocus(true);
				}

				public void onSuccess(ArrayList<ViewedPhotos> result) {
					
					deckPanel.clear();
					photos = result;
					FlexTable grid = new FlexTable();
					int col =0,row=0;
					for(final ViewedPhotos v:result)
					{
						VerticalPanel vpanel = new VerticalPanel();
						Image imgp = new Image();
						imgp.setUrl(v.getUrl());
						vpanel.add(imgp);
						Image img = new Image();
						img.setUrl(v.getUrl());
						
						img.setHeight("100px");
						img.setWidth("100px");
						grid.setWidget(row,col,img);
						//grid.getFlexCellFormatter().setRowSpan(grid.getRowCount(), col, grid.getRowCount()+1);
						InlineLabel lbld = new InlineLabel("Description: " +v.getDesc());
						vpanel.add(lbld);
						InlineLabel lblt = new InlineLabel("Tags: " +v.getTag());
						vpanel.add(lblt);
						col++;
						//if(v.getViewers()!=null && v.getViewers().size()>0)
						//{
							for(int i=0;i<v.getViewers().size();i++)
							{
								
								Hyperlink commenterLink = new Hyperlink(v.getViewers().get(i), v.getViewerids().get(i).toString());
								vpanel.add(commenterLink);
								
								InlineLabel lbl = new InlineLabel("" +v.getComments().get(i));
								vpanel.add(lbl);
							}
							Button btn1 = new Button("Comment and Rate");
							Button btn2 = new Button("Delete Photo");
							btn2.addClickHandler(new DeleteHandler(v.getPhotoid()));
							btn1.addClickHandler(new ClickHandler(){
								public void onClick(ClickEvent e)
								{
									postComment.addClickHandler(new CommentHandler(v.getPhotoid(),v.getRating()));
									commentBox.center();								
								}
							});
							vpanel.add(btn1);
							vpanel.add(btn2);							
						//}
						//else
						//{
							//InlineLabel lbl = new InlineLabel(v.getDesc());
							//vpanel.add(lbl);
						//}
							if(col>3){
							col=0;
							row++;
							}
						 final PopupPanel imagePopup = new PopupPanel(true);
						    imagePopup.setAnimationEnabled(true);
						    imagePopup.setWidget(vpanel);
						    img.addClickHandler(new ClickHandler(){
						    	public void onClick(ClickEvent e)
						    	{
						    		imagePopup.center();
						    	}
						    });
						
					}
					deckPanel.add(grid);
					if(result.size()==0 || result==null)
					{
						deckPanel.clear();
						deckPanel.add(new HTML("No such photo is available or is visible to you."));
					}
					
				}
			});
	}
	
	
	public void getSearchResults(String query){
		
		if(query!=null)
		{
		photoService.searchForPhotos(query, userId, new AsyncCallback<ArrayList<ViewedPhotos>>() {
			public void onFailure(Throwable caught) {
				commentBox.hide();
				// Show the RPC error message to the user
				dialogBox
						.setText("Remote Procedure Call - Failure");
				serverResponseLabel
						.addStyleName("serverResponseLabelError");
				serverResponseLabel.setHTML(SERVER_ERROR+" "+caught.getMessage());
				dialogBox.center();
				caught.printStackTrace();
				closeButton.setFocus(true);
			}

			public void onSuccess(ArrayList<ViewedPhotos> result) {
				
				deckPanel.clear();
				photos = result;
				FlexTable grid = new FlexTable();
				int col =0,row=0;
				for(final ViewedPhotos v:result)
				{
					VerticalPanel vpanel = new VerticalPanel();
					Image imgp = new Image();
					imgp.setUrl(v.getUrl());
					vpanel.add(imgp);
					Image img = new Image();
					img.setUrl(v.getUrl());
					
					img.setHeight("100px");
					img.setWidth("100px");
					grid.setWidget(row,col,img);
					InlineLabel lbld = new InlineLabel("Description: " +v.getDesc());
					vpanel.add(lbld);
					InlineLabel lblt = new InlineLabel("Tags: " +v.getTag());
					vpanel.add(lblt);
					col++;
					//if(v.getViewers()!=null && v.getViewers().size()>0)
					//{
						for(int i=0;i<v.getViewers().size();i++)
						{
							
							Hyperlink commenterLink = new Hyperlink(v.getViewers().get(i), v.getViewerids().get(i).toString());
							vpanel.add(commenterLink);
							
							InlineLabel lbl = new InlineLabel("" +v.getComments().get(i));
							vpanel.add(lbl);
						}
						Button btn1 = new Button("Comment and Rate");
						Button btn2 = new Button("Delete Photo");
						btn2.addClickHandler(new DeleteHandler(v.getPhotoid()));
						btn1.addClickHandler(new ClickHandler(){
							public void onClick(ClickEvent e)
							{
								postComment.addClickHandler(new CommentHandler(v.getPhotoid(),v.getRating()));
								commentBox.center();								
							}
						});
								
						vpanel.add(btn1);
						vpanel.add(btn2);							
					//}
					//else
					//{
						//InlineLabel lbl = new InlineLabel(v.getDesc());
						//vpanel.add(lbl);
					//}
						if(col>3){
							col=0;
							row++;
							}
						
					 final PopupPanel imagePopup = new PopupPanel(true);
					    imagePopup.setAnimationEnabled(true);
					    imagePopup.setWidget(vpanel);
					    img.addClickHandler(new ClickHandler(){
					    	public void onClick(ClickEvent e)
					    	{
					    		imagePopup.center();
					    	}
					    });
					
				}
				deckPanel.add(grid);				
			}
		});
		}
	}
	
	private static String escapeHtml(String str) {
		if (str == null) {
			return null;
		}
		return str.replaceAll("&", "&amp;").replaceAll("<", "&lt;")
				.replaceAll(">", "&gt;");
	}
	
	public class PhotoAddHandler implements ClickHandler{

		
		@Override
		public void onClick(ClickEvent event) {
			newPhotoBox.center();
			if(url.getText()!=null && !url.getText().equals(""))
			{
				String u = url.getText();
				u=PhotoRegisterView.escapeHtml(u);
				String d = description.getText();
				d=PhotoRegisterView.escapeHtml(d);
				String t = tag.getText();
				t=PhotoRegisterView.escapeHtml(t);
				ArrayList<String> fnames = new ArrayList<String>();
				ArrayList<String> cnames = new ArrayList<String>();
				//get friends or circles
				if(circles.getSelectedIndex()>0)
				{
					for(int i=0; i<circles.getItemCount();i++)
					{
						if(circles.isItemSelected(i))
						{
							cnames.add(circles.getItemText(i));
						}
					}
				}
				if(friends.getSelectedIndex()>0)
				{
					for(int i=0; i<friends.getItemCount();i++)
					{
						if(friends.isItemSelected(i))
						{
							fnames.add(friends.getItemText(i));
						}
					}
				}
				boolean isPublic=false;
				if(vsLevel.getItemText(vsLevel.getSelectedIndex()).equals("Everyone"))
					isPublic=true;
				if(!u.isEmpty()){
					if(u.contains(".jpg")||u.contains(".png")|| u.contains(".bmp")||u.contains(".gif")|| u.contains(".tiff"))
					{
					photoService.insertPhoto(userId, d, t, u,cnames,fnames,isPublic, new AsyncCallback<Integer>(){

						@Override
						public void onFailure(Throwable caught) {
							newPhotoBox.hide();
							dialogBox
							.setText("Photo registration error");
					serverResponseLabel
							.addStyleName("serverResponseLabelError");
					serverResponseLabel.setHTML(SERVER_ERROR+" "+caught.getMessage());
					dialogBox.center();
					caught.printStackTrace();
					closeButton.setFocus(true);
							
						}

						@Override
						public void onSuccess(Integer result) {
							if(result>0){
								url.setText("");
								tag.setText("");
								description.setText("");
								circles.setEnabled(false);
								friends.setEnabled(false);		
							rootPanel.clear();
							onModuleLoad();
							}
						}
						
					});
					}
					else
					{
						url.setText("");
						tag.setText("");
						description.setText("");
						circles.setEnabled(false);
						friends.setEnabled(false);
						newPhotoBox.hide();
						dialogBox
						.setText("Remote Procedure Call - Failure");
				serverResponseLabel
						.addStyleName("serverResponseLabelError");
				serverResponseLabel.setHTML("invalid photo type");
				dialogBox.center();
				
				closeButton.setFocus(true);
					}
				}
				
				
			}
			
		}
		
	}
	
	public class DeleteHandler implements ClickHandler{

		public int pid;
		public DeleteHandler(int p){pid=p;}
		@Override
		public void onClick(ClickEvent event) {
			boolean confirmedDelete = Window.confirm("Are you sure you want to delete this photo?");
			if(confirmedDelete){
			photoService.deletePhoto(userId, pid, new AsyncCallback<Integer>(){

				@Override
				public void onFailure(Throwable caught) {
					dialogBox
					.setText("Remote Procedure Call - Failure");
			serverResponseLabel
					.addStyleName("serverResponseLabelError");
			serverResponseLabel.setHTML(SERVER_ERROR+" "+caught.getMessage());
			dialogBox.center();
			caught.printStackTrace();
			closeButton.setFocus(true);
					
				}
				

				@Override
				public void onSuccess(Integer result) {
					Window.alert("NOTE: Your photo has been deleted!");
					rootPanel.clear();
					onModuleLoad();
				}
			
			});
			}
			
		}
		
	}
	
	
	public class CommentHandler implements ClickHandler{

		public int photoId;
		public int rate;
		public CommentHandler(int p,int r)
		{
			photoId=p;
			rate=r;
		}
		@Override
		public void onClick(ClickEvent event) {
			
			commentBox.center();
			if(comment.getText()!=null && !comment.getText().equals(""))
			{
				String cm=comment.getText();
				cm=PhotoRegisterView.escapeHtml(cm);
				if(!cm.isEmpty())
				{
					int rt = Integer.parseInt(rating.getItemText(rating.getSelectedIndex()));
					if(rt!=rate)
						rate=rt;
					photoService.updateViewedPhoto(userId, photoId, rate, cm, new AsyncCallback<Integer>(){

						@Override
						public void onFailure(Throwable caught) {
							dialogBox
							.setText("Remote Procedure Call - Failure");
					serverResponseLabel
							.addStyleName("serverResponseLabelError");
					serverResponseLabel.setHTML(SERVER_ERROR+" "+caught.getMessage());
					dialogBox.center();
					caught.printStackTrace();
					closeButton.setFocus(true);
							
						}

						@Override
						public void onSuccess(Integer result) {
							commentBox.hide();
							comment.setText("");
							System.out.println(photos);
							rootPanel.clear();
							onModuleLoad();
							/*if(photos.size()>0)
							{
								deckPanel.clear();
								for(ViewedPhotos v:photos)
								{
									VerticalPanel vpanel = new VerticalPanel();
									Image img = new Image();
									img.setUrl(v.getUrl());
									img.setHeight("150px");
									img.setWidth("150px");
									vpanel.add(img);
									InlineLabel lbld = new InlineLabel("Description: " +v.getDesc());
									vpanel.add(lbld);

									if(v.getViewers()!=null && v.getViewers().size()>0)
									{
										for(int i=0;i<v.getViewers().size();i++)
										{
											
											Hyperlink commenterLink = new Hyperlink(v.getViewers().get(i), v.getViewerids().get(i).toString());
											vpanel.add(commenterLink);
											
											InlineLabel lbl = new InlineLabel("" +v.getComments().get(i));
											vpanel.add(lbl);
										}
										Button btn = new Button("Comment");
										btn.addClickHandler(new CommentHandler(v.getPhotoid(),v.getRating()));
										vpanel.add(btn);							
									}
									else
									{
										InlineLabel lbl = new InlineLabel(v.getDesc());
										vpanel.add(lbl);
									}
									deckPanel.add(vpanel);
								}
							}*/
						}
						
					});
				}
			}
		}
	}
}
